const { HTTP_STATUS, ERROR_CODES } = require('../utils/constants')
const logger = require('../utils/logger')
const config = require('../config')

/**
 * 错误处理中间件
 */
const errorHandler = (err, req, res, next) => {
  // 如果响应已经发送，则交给默认的Express错误处理器
  if (res.headersSent) {
    return next(err)
  }

  // 记录错误日志
  logger.error('Error occurred', {
    error: err.message,
    stack: err.stack,
    url: req.url,
    method: req.method,
    ip: req.ip,
    userAgent: req.get('User-Agent'),
    userId: req.user?.id,
    timestamp: new Date().toISOString()
  })

  // 解析错误类型和状态码
  const errorInfo = parseError(err)
  
  // 构建错误响应
  const errorResponse = {
    success: false,
    error: {
      code: errorInfo.code,
      message: errorInfo.message,
      timestamp: new Date().toISOString()
    }
  }

  // 在开发环境中包含更多错误信息
  if (config.server.env === 'development') {
    errorResponse.error.stack = err.stack
    errorResponse.error.details = err.details || null
  }

  // 发送错误响应
  res.status(errorInfo.status).json(errorResponse)
}

/**
 * 解析错误信息
 */
function parseError(err) {
  // 自定义应用错误
  if (err.code && err.message) {
    return {
      status: getStatusFromErrorCode(err.code),
      code: err.code,
      message: err.message
    }
  }

  // JWT错误
  if (err.name === 'JsonWebTokenError') {
    return {
      status: HTTP_STATUS.UNAUTHORIZED,
      code: ERROR_CODES.TOKEN_INVALID,
      message: '无效的访问令牌'
    }
  }

  if (err.name === 'TokenExpiredError') {
    return {
      status: HTTP_STATUS.UNAUTHORIZED,
      code: ERROR_CODES.TOKEN_EXPIRED,
      message: '访问令牌已过期'
    }
  }

  // Joi验证错误
  if (err.name === 'ValidationError' && err.isJoi) {
    return {
      status: HTTP_STATUS.BAD_REQUEST,
      code: ERROR_CODES.VALIDATION_ERROR,
      message: '请求参数验证失败'
    }
  }

  // 语法错误（通常是JSON解析错误）
  if (err instanceof SyntaxError && err.status === 400 && 'body' in err) {
    return {
      status: HTTP_STATUS.BAD_REQUEST,
      code: ERROR_CODES.INVALID_JSON,
      message: '无效的JSON格式'
    }
  }

  // 文件系统错误
  if (err.code === 'ENOENT') {
    return {
      status: HTTP_STATUS.NOT_FOUND,
      code: ERROR_CODES.FILE_NOT_FOUND,
      message: '文件不存在'
    }
  }

  if (err.code === 'EACCES') {
    return {
      status: HTTP_STATUS.FORBIDDEN,
      code: ERROR_CODES.FILE_ACCESS_DENIED,
      message: '文件访问被拒绝'
    }
  }

  // 网络错误
  if (err.code === 'ECONNREFUSED') {
    return {
      status: HTTP_STATUS.SERVICE_UNAVAILABLE,
      code: ERROR_CODES.SERVICE_UNAVAILABLE,
      message: '服务暂时不可用'
    }
  }

  if (err.code === 'ETIMEDOUT') {
    return {
      status: HTTP_STATUS.REQUEST_TIMEOUT,
      code: ERROR_CODES.REQUEST_TIMEOUT,
      message: '请求超时'
    }
  }

  // 数据库相关错误（如果使用数据库）
  if (err.name === 'MongoError' || err.name === 'MongooseError') {
    return {
      status: HTTP_STATUS.INTERNAL_SERVER_ERROR,
      code: ERROR_CODES.DATABASE_ERROR,
      message: '数据库操作失败'
    }
  }

  // 默认内部服务器错误
  return {
    status: HTTP_STATUS.INTERNAL_SERVER_ERROR,
    code: ERROR_CODES.INTERNAL_ERROR,
    message: '服务器内部错误'
  }
}

/**
 * 根据错误代码获取HTTP状态码
 */
function getStatusFromErrorCode(errorCode) {
  const statusMap = {
    // 认证相关错误
    [ERROR_CODES.TOKEN_MISSING]: HTTP_STATUS.UNAUTHORIZED,
    [ERROR_CODES.TOKEN_INVALID]: HTTP_STATUS.UNAUTHORIZED,
    [ERROR_CODES.TOKEN_EXPIRED]: HTTP_STATUS.UNAUTHORIZED,
    [ERROR_CODES.REFRESH_TOKEN_MISSING]: HTTP_STATUS.UNAUTHORIZED,
    [ERROR_CODES.INVALID_REFRESH_TOKEN]: HTTP_STATUS.UNAUTHORIZED,
    [ERROR_CODES.AUTHENTICATION_REQUIRED]: HTTP_STATUS.UNAUTHORIZED,
    [ERROR_CODES.INVALID_CREDENTIALS]: HTTP_STATUS.UNAUTHORIZED,
    
    // 授权相关错误
    [ERROR_CODES.INSUFFICIENT_PERMISSIONS]: HTTP_STATUS.FORBIDDEN,
    [ERROR_CODES.ACCESS_DENIED]: HTTP_STATUS.FORBIDDEN,
    [ERROR_CODES.USER_DISABLED]: HTTP_STATUS.FORBIDDEN,
    [ERROR_CODES.USER_DELETED]: HTTP_STATUS.FORBIDDEN,
    
    // 资源不存在错误
    [ERROR_CODES.USER_NOT_FOUND]: HTTP_STATUS.NOT_FOUND,
    [ERROR_CODES.SESSION_NOT_FOUND]: HTTP_STATUS.NOT_FOUND,
    [ERROR_CODES.MESSAGE_NOT_FOUND]: HTTP_STATUS.NOT_FOUND,
    [ERROR_CODES.CONFIG_NOT_FOUND]: HTTP_STATUS.NOT_FOUND,
    [ERROR_CODES.FILE_NOT_FOUND]: HTTP_STATUS.NOT_FOUND,
    
    // 请求错误
    [ERROR_CODES.VALIDATION_ERROR]: HTTP_STATUS.BAD_REQUEST,
    [ERROR_CODES.INVALID_REQUEST]: HTTP_STATUS.BAD_REQUEST,
    [ERROR_CODES.INVALID_JSON]: HTTP_STATUS.BAD_REQUEST,
    [ERROR_CODES.INVALID_CONFIG_KEY]: HTTP_STATUS.BAD_REQUEST,
    
    // 冲突错误
    [ERROR_CODES.USER_ALREADY_EXISTS]: HTTP_STATUS.CONFLICT,
    [ERROR_CODES.CONFIG_ALREADY_EXISTS]: HTTP_STATUS.CONFLICT,
    
    // 操作不允许错误
    [ERROR_CODES.OPERATION_NOT_ALLOWED]: HTTP_STATUS.METHOD_NOT_ALLOWED,
    [ERROR_CODES.CANNOT_DELETE_DEFAULT]: HTTP_STATUS.METHOD_NOT_ALLOWED,
    
    // 限制错误
    [ERROR_CODES.RATE_LIMIT_EXCEEDED]: HTTP_STATUS.TOO_MANY_REQUESTS,
    [ERROR_CODES.FILE_TOO_LARGE]: HTTP_STATUS.PAYLOAD_TOO_LARGE,
    
    // 服务器错误
    [ERROR_CODES.INTERNAL_ERROR]: HTTP_STATUS.INTERNAL_SERVER_ERROR,
    [ERROR_CODES.DATABASE_ERROR]: HTTP_STATUS.INTERNAL_SERVER_ERROR,
    [ERROR_CODES.AI_SERVICE_ERROR]: HTTP_STATUS.INTERNAL_SERVER_ERROR,
    [ERROR_CODES.ENCRYPTION_ERROR]: HTTP_STATUS.INTERNAL_SERVER_ERROR,
    
    // 外部服务错误
    [ERROR_CODES.SERVICE_UNAVAILABLE]: HTTP_STATUS.SERVICE_UNAVAILABLE,
    [ERROR_CODES.REQUEST_TIMEOUT]: HTTP_STATUS.REQUEST_TIMEOUT
  }
  
  return statusMap[errorCode] || HTTP_STATUS.INTERNAL_SERVER_ERROR
}

/**
 * 404错误处理中间件
 */
const notFoundHandler = (req, res, next) => {
  const error = {
    status: HTTP_STATUS.NOT_FOUND,
    code: ERROR_CODES.ROUTE_NOT_FOUND,
    message: `路由 ${req.method} ${req.path} 不存在`
  }

  logger.warn('Route not found', {
    method: req.method,
    path: req.path,
    ip: req.ip,
    userAgent: req.get('User-Agent')
  })

  res.status(error.status).json({
    success: false,
    error: {
      code: error.code,
      message: error.message,
      timestamp: new Date().toISOString()
    }
  })
}

/**
 * 异步错误包装器
 */
const asyncHandler = (fn) => {
  return (req, res, next) => {
    Promise.resolve(fn(req, res, next)).catch(next)
  }
}

/**
 * 创建自定义错误
 */
class AppError extends Error {
  constructor(code, message, details = null) {
    super(message)
    this.name = 'AppError'
    this.code = code
    this.details = details
    
    // 保持堆栈跟踪
    if (Error.captureStackTrace) {
      Error.captureStackTrace(this, AppError)
    }
  }
}

/**
 * 创建验证错误
 */
class ValidationError extends Error {
  constructor(message, details = null) {
    super(message)
    this.name = 'ValidationError'
    this.code = ERROR_CODES.VALIDATION_ERROR
    this.details = details
    
    if (Error.captureStackTrace) {
      Error.captureStackTrace(this, ValidationError)
    }
  }
}

/**
 * 创建认证错误
 */
class AuthenticationError extends Error {
  constructor(code = ERROR_CODES.AUTHENTICATION_REQUIRED, message = '需要身份验证') {
    super(message)
    this.name = 'AuthenticationError'
    this.code = code
    
    if (Error.captureStackTrace) {
      Error.captureStackTrace(this, AuthenticationError)
    }
  }
}

/**
 * 创建授权错误
 */
class AuthorizationError extends Error {
  constructor(code = ERROR_CODES.INSUFFICIENT_PERMISSIONS, message = '权限不足') {
    super(message)
    this.name = 'AuthorizationError'
    this.code = code
    
    if (Error.captureStackTrace) {
      Error.captureStackTrace(this, AuthorizationError)
    }
  }
}

/**
 * 创建资源不存在错误
 */
class NotFoundError extends Error {
  constructor(resource = '资源', id = null) {
    const message = id ? `${resource} (ID: ${id}) 不存在` : `${resource}不存在`
    super(message)
    this.name = 'NotFoundError'
    this.code = ERROR_CODES.RESOURCE_NOT_FOUND
    
    if (Error.captureStackTrace) {
      Error.captureStackTrace(this, NotFoundError)
    }
  }
}

/**
 * 创建冲突错误
 */
class ConflictError extends Error {
  constructor(message = '资源冲突') {
    super(message)
    this.name = 'ConflictError'
    this.code = ERROR_CODES.RESOURCE_CONFLICT
    
    if (Error.captureStackTrace) {
      Error.captureStackTrace(this, ConflictError)
    }
  }
}

/**
 * 处理未捕获的异常
 */
process.on('uncaughtException', (err) => {
  logger.error('Uncaught Exception', {
    error: err.message,
    stack: err.stack
  })
  
  // 优雅地关闭应用程序
  process.exit(1)
})

/**
 * 处理未处理的Promise拒绝
 */
process.on('unhandledRejection', (reason, promise) => {
  logger.error('Unhandled Rejection', {
    reason: reason instanceof Error ? reason.message : reason,
    stack: reason instanceof Error ? reason.stack : null,
    promise: promise
  })
  
  // 优雅地关闭应用程序
  process.exit(1)
})

module.exports = {
  errorHandler,
  notFoundHandler,
  asyncHandler,
  AppError,
  ValidationError,
  AuthenticationError,
  AuthorizationError,
  NotFoundError,
  ConflictError
}